using System.Data.Linq;
using System.Linq;
using MimeCloud.Foundations.Extensions;

namespace MimeCloud.Foundations.Repositories
{
    public class LinqToSqlContext : IDataContext
    {
        private readonly DataContext _context;

        public LinqToSqlContext(DataContext context)
        {
            _context = context;
        }

        /// <summary>
        /// Gets the repository for the given type of entities
        /// </summary>
        /// <typeparam name="T">The type of the entity</typeparam>
        /// <returns>The repository of the given type</returns>
        public IQueryable<T> Repository<T>() where T : class
        {
            ITable table = _context.GetTable<T>();
            return table.Cast<T>();
        }

        /// <summary>
        /// Deletes the specified entity from the repository
        /// </summary>
        /// <typeparam name="T">The type of the entity</typeparam>
        /// <param name="item">The entity to delete</param>
        public void Delete<T>(T item) where T : class
        {
            ITable table = _context.GetTable<T>();
            table.DeleteOnSubmit(item);
        }

        /// <summary>
        /// Adds a new entity to the repository
        /// </summary>
        /// <typeparam name="T">The type of the entity</typeparam>
        /// <param name="item">The entity to add</param>
        public void Insert<T>(T item) where T : class
        {
            ITable table = _context.GetTable<T>();
            table.InsertOnSubmit(item);
        }

        /// <summary>
        /// Commits the changes for this unit of work to the repository
        /// </summary>
        public void Commit()
        {
            _context.SubmitChanges();
            OnCommitExecuted(null);
        }

        public void Dispose()
        {
            // we don't assume to manage the lifetime of the data 
            // context, so there's nothing to dispose
        }

        #region IDataContext Members

        /// <summary>
        /// Occurs when [commit executed].
        /// </summary>
        public event System.EventHandler CommitExecuted;

        /// <summary>
        /// Raises the <see cref="E:CommitExecuted"/> event.
        /// </summary>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        public void OnCommitExecuted(System.EventArgs e)
        {
            var handler = CommitExecuted;
            if (handler != null)
                handler(this, e);
        }

        #endregion

        #region IDataContext Members


        /// <summary>
        /// Deletes the specified entity from the repository
        /// </summary>
        /// <typeparam name="T">The type of the entity</typeparam>
        public void DeleteAll<T>() where T : class
        {
            Repository<T>().ForEach(Delete);
        }

        #endregion
    }
}